使用 Select Url API 輪播廣告素材

使用 Select URL API 運用 Shared Storage API,決定使用者在各網站上看到的廣告素材。

廣告客戶或內容製作者可能會想在廣告活動中套用不同的內容輪播策略,並輪播內容或廣告素材來提高成效。您可以使用 Select URL API 在不同網站上執行不同的輪替策略,例如依序輪替和平均輪替。

您可以使用 Select URL API 廣告素材輪替功能,儲存廣告素材 ID、觀看次數和使用者互動等資料,藉此決定使用者在不同網站上看到的廣告素材。

如要進一步瞭解基礎 API 和選取功能的運作方式,請參閱 Select URL API 說明文件

試用廣告素材輪播

如要嘗試廣告素材輪替,請務必啟用 Select URL API 和 Shared Storage:

  • chrome://settings/content/siteData 中選取 Allow sites to save data on your deviceDelete data sites have saved to your device when you close all windows
  • chrome://settings/adPrivacy/sites 中選取 Site-suggested ads

如要查看本文件中程式碼範例的即時版本,請試用Shared Storage 即時示範

程式碼範例示範

在這個例子中:

  • creative-rotation.js 是第三方指令碼,用於定義要輪替的內容,以及決定要選取及顯示的下一個內容的任何資料,例如本例中的權重。發布商網頁會執行這段指令碼。這個指令碼會呼叫 Shared Storage 工作元件,根據儲存空間中的可用資料和可選取的網址清單,判斷要顯示哪些內容。

  • creative-rotation-worklet.js 是第三方共用儲存空間工作區塊,可查詢輪替策略、計算下次要發布的內容,並傳回該內容。

示範的運作方式

  1. 使用者造訪發布商網頁時,網頁會載入第三方的 creative-rotation.js 指令碼。廣告輪替指令碼負責載入及執行共用儲存空間工作區。這個指令碼會為工作區呼叫提供可選取的網址清單。
  2. 如果工作區塊尚未初始化共用儲存空間,系統會使用初始廣告素材輪替策略和廣告素材索引來初始化儲存空間。這個示範中使用的初始輪替策略是序列策略。
  3. 工作릿會從共用儲存空間讀取旋轉模式,並傳回下一則廣告的索引。在序列輪替模式下,它也會使用新值更新共用儲存空間中的廣告素材索引,以便在下次呼叫時使用。工作區會根據呼叫 selectURL 時使用的 resolveToConfig 值,傳回 FencedFrameConfig 或不透明的 URN 物件。
  4. 廣告素材輪播指令碼會在 Fenced Frame 或 iframe 中顯示所選廣告。如要進一步瞭解回傳類型,請參閱「顯示廣告」說明文件。
  5. 使用者變更旋轉模式時,Shared Storage Worklet 會更新儲存在 Shared Storage 中的廣告素材旋轉模式值。
  6. 重新載入發布商網頁時,系統會重複步驟 1 至 4,根據所選輪替策略選取下一個要顯示的廣告

程式碼範例

以下是 creative-rotation.jscreative-rotation-worklet.js 的程式碼範例。

creative-rotation.js

const contentProducerUrl = 'https://your-server.example';

// Ad config with the URL of the ad, a probability weight for rotation, and the clickthrough rate.
const DEMO_AD_CONFIG = [
  {
    url: `${contentProducerUrl}/ads/ad-1.html`,
    weight: 0.7,
  },
  {
    url: `${contentProducerUrl}/ads/ad-2.html`,
    weight: 0.2,
  },
  {
    url: `${contentProducerUrl}/ads/ad-3.html`,
    weight: 0.1,
  },
];

async function setRotationMode(rotationMode) {
  // Load the worklet module
  const creativeRotationWorklet = await window.sharedStorage.createWorklet(
    `${contentProducerUrl}/url-selection/creative-rotation-worklet.js`,
    { dataOrigin: 'script-origin' }
  );

  await creativeRotationWorklet.run('set-rotation-mode', {
    data: { rotationMode }
  });
  console.log(`creative rotation mode set to ${rotationMode}`);
}

async function injectAd() {
  // Load the worklet module
  const creativeRotationWorklet = await window.sharedStorage.createWorklet(
    `${contentProducerUrl}/url-selection/creative-rotation-worklet.js`,
    { dataOrigin: 'script-origin' }
  );

  const urls = DEMO_AD_CONFIG.map(({ url }) => ({ url }));

  // Resolve the selectURL call to a fenced frame config only when it exists on the page
  const resolveToConfig = typeof window.FencedFrameConfig !== 'undefined';

  // Run the URL selection operation to determine the next ad that should be rendered
  const selectedUrl = await creativeRotationWorklet.selectURL('creative-rotation', urls, {
    data: DEMO_AD_CONFIG,
    resolveToConfig
  });

  const adSlot = document.getElementById('ad-slot');

  if (resolveToConfig && selectedUrl instanceof FencedFrameConfig) {
    adSlot.config = selectedUrl;
  } else {
    adSlot.src = selectedUrl;
  }
}

injectAd();

creative-rotation-worklet.js

class SelectURLOperation {
  async run(urls, data) {
    // Initially set the storage to sequential mode for the demo
    await SelectURLOperation.seedStorage();

    // Read the rotation mode from Shared Storage
    const rotationMode = await sharedStorage.get('creative-rotation-mode');

    // Generate a random number to be used for rotation
    const randomNumber = Math.random();

    let index;

    switch (rotationMode) {
      /**
       * Sequential rotation
       * - Rotates the creatives in order
       * - Example: A -> B -> C -> A ...
       */
      case 'sequential':
        const currentIndex = await sharedStorage.get('creative-rotation-index');
        index = parseInt(currentIndex, 10);
        const nextIndex = (index + 1) % urls.length;

        console.log(`index = ${index} / next index = ${nextIndex}`);

        await sharedStorage.set('creative-rotation-index', nextIndex.toString());
        break;

      /**
       * Evenly-distributed rotation
       * - Rotates the creatives with equal probability
       * - Example: A=33% / B=33% / C=33%
       */
      case 'even-distribution':
        index = Math.floor(randomNumber * urls.length);
        break;

      /**
       * Weighted rotation
       * - Rotates the creatives with weighted probability
       * - Example: A=70% / B=20% / C=10%
       */
      case 'weighted-distribution':
        console.log('data = ', JSON.stringify(data));
        // Find the first URL where the cumnulative sum of the weights
        // exceed the random number. The array is sorted by the weight
        // in descending order.
        let weightSum = 0;
        const { url } = data
          .sort((a, b) => b.weight - a.weight)
          .find(({ weight }) => {
            weightSum += weight;
            return weightSum > randomNumber;
          });

        index = urls.indexOf(url);
        break;

      default:
        index = 0;
    }

    console.log(JSON.stringify({ index, randomNumber, rotationMode }));
    return index;
  }

  // Set the mode to sequential and set the starting index to 0.
  static async seedStorage() {
    await sharedStorage.set('creative-rotation-mode', 'sequential', {
      ignoreIfPresent: true,
    });

    await sharedStorage.set('creative-rotation-index', 0, {
      ignoreIfPresent: true,
    });
  }
}

class SetRotationModeOperation {
  async run({ rotationMode }) {
    await sharedStorage.set('creative-rotation-mode', rotationMode);
  }
}

// Register the operation as 'creative-rotation'
register('creative-rotation', SelectURLOperation);
register('set-rotation-mode', SetRotationModeOperation);

附有螢幕截圖的操作說明

  1. 如要使用 Select URL API 和共用儲存空間存取廣告素材輪播功能,請前往 https://shared-storage-demo.web.app/。選擇「廣告素材輪播」示範。

  2. 選擇以「發布商 A」的身份查看示範影片。系統會將您重新導向至 https://shared-storage-demo-publisher-a.web.app/creative-rotation。頁面會根據儲存在 Shared Storage 中的廣告素材輪替資料 (透過 Select URL API 存取) 載入編號內容。廣告素材輪播的示範模式包括依序、平均分配和加權分配。工作區塊會執行邏輯,選取在 iframe 中顯示的內容。下圖為發布者頁面。這張螢幕截圖顯示發布商 A https://shared-storage-demo-publisher-a.web.app/creative-rotation 的網頁內容,其中包含一個內嵌框架,內含數字 1 的圖片,以及控制項,可選擇創意輪替策略 (依序、平均分配和加權分配)。另外還有一個文字區域,說明不同的廣告素材輪替策略,以及 iframe 和 worklet 邏輯的連結。

    螢幕截圖:顯示發布商 A 網頁,內含數字 1 的圖片,以及用於選擇廣告素材輪替策略的控制項。

  3. 如要查看 Shared Storage 中儲存的內容,請在 Chrome 開發人員工具中依序前往「Application」>「Shared Storage」。系統會為共用儲存空間建立兩個項目。https://shared-storage-demo-publisher-a.web.app 來源可使用空白儲存空間。這會包含該來源專屬的儲存空間,在本示範中會保持空白,因為發布者不需要寫入共用儲存空間。請注意,如果您稍後再次造訪該頁面進行示範,系統會為發布商 B 建立類似的儲存空間。螢幕截圖顯示 Chrome 開發人員工具,特別是「應用程式」部分,並醒目顯示「共用儲存空間」項目,以及「發布者 A」來源的空白儲存空間 https://shared-storage-demo-publisher-a.web.app

    Chrome 開發人員工具顯示發布者 A 的「Shared Storage」為空白。

  4. 系統會為 https://shared-storage-demo-content-producer.web.app 來源建立另一個 Shared Storage 項目。這是發布商網頁中嵌入的第三方 iframe 儲存空間。這個儲存空間將用於在兩個可用的發布商之間分享資料,協調廣告素材選擇。這個共用儲存空間會儲存兩個鍵/值組合,用於儲存顯示廣告素材和輪替策略的相關資訊。在示範中使用的第 1 個鍵是 creative-rotation-index,其值為目前的連續模式廣告素材索引。第二個鍵是 creative-rotation-mode,用於指定使用的輪替策略。螢幕截圖:顯示 Chrome 開發人員工具,特別是來源網址 https://shared-storage-demo-content-producer.web.app 的共用儲存空間。儲存空間並非空白,而是顯示已儲存的兩個鍵/值組合。第一個鍵是 creative-rotation-index,值為 1。第二個儲存的鍵是 creative-rotation-mode,其值為「sequential」

    螢幕截圖顯示 Chrome 開發人員工具共用儲存空間,其中包含兩個鍵/值組合:creative-rotation-index: 1 和 creative-rotation-mode: "sequential."

  5. 在依序模式下重新整理網頁時,系統會依序顯示 1、2、3、1、… 等廣告素材。在依序模式下,廣告素材輪播索引值會根據顯示的廣告素材索引而變更。螢幕截圖:顯示「發布者 A」網頁,以及顯示「共用儲存空間」部分的 DevTools。網頁上的廣告素材標示為 2,而廣告素材輪播索引值則標示為 2,與顯示的廣告素材索引相符。目前的廣告素材輪播模式顯示為依序。

    螢幕截圖:顯示發布商 A 的網頁和開發人員工具。顯示的廣告素材為 2,creative-rotation-mode 為 sequential,creative-rotation-index 為 2。

  6. 使用控制按鈕變更廣告素材輪播模式後,廣告素材輪播模式鍵的值會更新為對應策略。工作區程式碼會使用這個值,選擇要在 iframe 中顯示的下一個廣告素材。請注意,廣告素材輪播索引值的儲存值不會變更,除非輪播模式為「依序」。螢幕截圖:顯示「發布者 A」網頁,以及顯示「共用儲存空間」部分的 DevTools。頁面上的廣告素材顯示為 1。醒目顯示廣告素材輪播模式已設為加權分配,並醒目顯示可將輪播模式設為加權分配的對應控制項。雖然顯示的廣告素材為 1,但 creative-rotation-index 的值為 2,因為系統不會使用或更新依序以外的輪播模式索引。

    螢幕截圖:顯示發布商 A 的網頁和開發人員工具。顯示的廣告素材為 1,creative-rotation-mode 為加權分配,creative-rotation-index 為 2 (未使用)。

  7. 前往「發布商 B」頁面,網址為 https://shared-storage-demo-publisher-b.web.app/creative-rotation。在依序模式中,系統應顯示「發布者 A」網址的下一個廣告素材。檢查內容製作者的「共用儲存空間」後,您會發現「發布商 A」和「發布商 B」共用相同的儲存空間,並使用該處的設定來選取要顯示的下一個廣告素材,以及要使用的輪替策略。螢幕截圖:顯示「Publisher B」網頁,以及顯示來源 https://shared-storage-demo-content-producer.web.app 的「Shared Storage」部分的 DevTools。網頁上的廣告素材顯示為 3。而醒目顯示的 creative-rotation 索引為 3,creative-rotation-mode 為 sequential。

    發布商 B 的網頁和開發人員工具。Shared Storage 廣告素材為 3,creative-rotation 索引為 3,creative-rotation-mode 為依序。

  8. 「發布者 B」的共用儲存空間為空白,與「發布者 A」的共用儲存空間類似。 螢幕截圖顯示 Chrome 開發人員工具,特別是「應用程式」部分,並醒目顯示「共用儲存空間」項目,以及「發布者 B」來源的空白儲存空間 https://shared-storage-demo-publisher-b.web.app。

    Chrome 開發人員工具顯示發布者 B 來源的空白 Shared Storage。

    用途

    請參閱本節,瞭解 Select URL API 的所有可用用途。我們會持續新增示例,以回應使用者意見並探索新的測試案例。

互動並分享意見回饋

請注意,Select URL API 提案仍在積極討論和開發中,可能會有所變動。

我們很期待聽到您對 Select URL API 的看法。

掌握最新消息

  • 電子報名單:訂閱我們的電子報名單,即可取得與 Select 網址和 Shared Storage API 相關的最新消息和公告。

需要協助嗎?